package com.atguigu.utils;

import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class MoreThreadTest {

    /**
     * 多线程批量插入数据
     *
     * @param platformTransactionManager 事务管理器
     * @param runnables                  多任务列表
     * @return 返回是否插入成功
     */
    public static boolean execute(PlatformTransactionManager platformTransactionManager, Runnable... runnables) {

        //判断非空
        if (runnables == null || runnables.length == 0) {
            throw new IllegalArgumentException("任务列表为空");
        }

        //任务数量
        int runnableLength = runnables.length;

        //任务成功数量
        AtomicInteger success = new AtomicInteger();

        //执行完成的任务的返回值集合
        List<Future<?>> futures = new ArrayList<>();

        //循环屏障（等待所有任务一起完成）
        CyclicBarrier cyclicBarrier = new CyclicBarrier(runnableLength);

        //创建线程池
        ExecutorService threadPools = Executors.newFixedThreadPool(runnableLength);

        try {
            for (Runnable runnable : runnables) {
                Future<?> future = threadPools.submit(() -> {
                    TransactionStatus transactionStatus = null;
                    try {
                        //开启事务
                        transactionStatus = platformTransactionManager.getTransaction(new DefaultTransactionAttribute());

                        //执行任务
                        runnable.run();

                        //成功数量
                        success.incrementAndGet();
                    } catch (TransactionException e) {
                        System.out.println(e.getMessage());
                    } finally {
                        try {
                            //任务等待
                            cyclicBarrier.await();
                        } catch (Exception e) {
                            System.out.println(e.getMessage());
                        }
                    }

                    //通过循环栅栏阻塞到达这里时让所有线程的任务都执行成功，若是其中有一个失败，则不同线程各自回滚（这样就实现了多线程的事务提交和回滚）
                    if (transactionStatus != null) {
                        //成功任务数量等于最大任务数量
                        if (success.get() == runnableLength) {
                            //执行成功提交多线程事务（提交当前线程事务）
                            platformTransactionManager.commit(transactionStatus);
                        } else {
                            //执行失败回滚多线程事务（回滚当前线程事务）
                            platformTransactionManager.rollback(transactionStatus);
                        }
                    }
                });

                //添加完成任务的返回值
                futures.add(future);
            }

            for (Future<?> future : futures) {
                try {
                    future.get();
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            }
        } finally {
            threadPools.shutdown();
        }

        //如果所有任务都成功完成，则返回true；否则返回false
        return success.get() == runnableLength;
    }
}
